#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <glm/glm.hpp>
#include <string>
#include <sstream>
namespace py = pybind11;

template<typename T>
static void declareGlmVec3(py::module &mod, const std::string &typestr)
{
    using class_type = glm::tvec3<T>;
    auto pyclass_name = std::string("Vec3") + typestr;
    py::class_<class_type, std::shared_ptr<class_type>>cls(mod, pyclass_name.c_str(), py::buffer_protocol());

    cls.def(py::init());
    cls.def(py::init<T, T, T>());
    cls.def("__getitem__", [](const glm::tvec3<T> &a,int index) {return a[index]; });
    cls.def("__repr__", [](const glm::tvec3<T> & a)
    {
        std::string ret;
        std::stringstream ss;
        ss << "[" << a[0] << "," << a[1] << "," << a[2] << "]";
        ss >> ret;
        return ret;
    });
    cls.def_buffer([](class_type &buff)->py::buffer_info {
        return py::buffer_info(
            &buff,
            sizeof(T),
            py::format_descriptor<T>::format(),
            1,
            { 3 },
            { sizeof(T) }
        );
    });
}

void initGlmVector(py::module &m)
{
    declareGlmVec3<float>(m, std::string("F"));
    declareGlmVec3<double>(m, std::string("D"));
}
